package org.dtrd.modules.suggest.service.impl;

import org.dtrd.common.util.CheckUtil;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.pay.PayConstant;
import org.dtrd.modules.doctor.entity.bean.DoctorInfo;
import org.dtrd.modules.doctor.entity.bean.DoctorSigninSuggestDetail;
import org.dtrd.modules.doctor.entity.bean.SigninSuggestDetail;
import org.dtrd.modules.doctor.entity.po.DtrdEntRdDoctorSigninSuggest;
import org.dtrd.modules.doctor.service.IDtrdEntRdDoctorSigninSuggestService;
import org.dtrd.modules.doctor.service.impl.DtrdEntRdDoctorServiceImpl;
import org.dtrd.modules.doctor.service.impl.DtrdEntRdDoctorSigninSuggestServiceImpl;
import org.dtrd.modules.record.entity.bean.SigninSuggestBean;
import org.dtrd.modules.record.entity.po.DtrdEntRdSigninSuggest;
import org.dtrd.modules.record.service.impl.DtrdEntRdSigninSuggestServiceImpl;
import org.dtrd.modules.shop.entity.bean.OrderListInfo;
import org.dtrd.modules.suggest.entity.bean.*;
import org.dtrd.modules.suggest.entity.po.DtrdEntRdSigninRecordSuggest;
import org.dtrd.modules.suggest.mapper.DtrdEntRdSigninRecordSuggestMapper;
import org.dtrd.modules.suggest.service.IDtrdEntRdSigninRecordSuggestService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.dtrd.modules.suggest.entity.bean.SigninRecordSuggestDetail;
import org.dtrd.modules.suggest.entity.bean.SigninRecordSuggestListInfo;
import org.dtrd.modules.suggest.entity.bean.SigninRecordSuggestListRequest;
import org.dtrd.modules.suggest.entity.bean.SigninRecordSuggestPageRequest;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 打卡记录建议表 服务实现类
 * </p>
 *
 * @author sun
 * @since 2022-08-03
 */
@DS("multi-datasource1")
@Service
public class DtrdEntRdSigninRecordSuggestServiceImpl extends ServiceImpl<DtrdEntRdSigninRecordSuggestMapper, DtrdEntRdSigninRecordSuggest> implements IDtrdEntRdSigninRecordSuggestService {

    private DtrdEntRdSigninRecordSuggestMapper dtrdEntRdSigninRecordSuggestMapper;

    @Autowired
    private DtrdEntRdDoctorServiceImpl doctorService;

    @Autowired
    private DtrdEntRdDoctorSigninSuggestServiceImpl suggestService;

    @Autowired
    private DtrdEntRdSigninSuggestServiceImpl rdSuggestService;

    @Autowired
    private IDtrdEntRdSigninRecordSuggestService signinRecordSuggestService;

    @Override
    public List<SigninRecordSuggestListInfo> getSigninRecordSuggestList(SigninRecordSuggestListRequest request) {
        LambdaQueryWrapper<DtrdEntRdSigninRecordSuggest> queryWrapper = baseQueryWrapper();
        if (request.getRecordId() != null) {
            queryWrapper.eq(DtrdEntRdSigninRecordSuggest::getRecordId, request.getRecordId());
        }
        if (request.getRecordDate() != null) {
            queryWrapper.eq(DtrdEntRdSigninRecordSuggest::getRecordDate, request.getRecordDate());
        }

        List<DtrdEntRdSigninRecordSuggest> poList = list(queryWrapper);
        List<SigninRecordSuggestListInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
//            dtoList = poList.stream().map(SigninRecordSuggestListInfo::new).collect(Collectors.toList());
            dtoList = poList.stream().map(po -> {
                SigninRecordSuggestListInfo signinRecordSuggestListInfo = new SigninRecordSuggestListInfo(po);
                if (po.getSuggestDoctorId() != null) {
                    signinRecordSuggestListInfo.setSuggestDoctorName(doctorService.getDoctorName(po.getSuggestDoctorId()));
                }
                return signinRecordSuggestListInfo;
            }).collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public List<SigninRecordSuggestListInfo> getSigninRecordSuggestListById(Integer recordId) {
        LambdaQueryWrapper<DtrdEntRdSigninRecordSuggest> queryWrapper = baseQueryWrapper();
//        queryWrapper.eq(DtrdEntRdSigninRecordSuggest::getRecordId, request.getRecordId());
        queryWrapper.eq(DtrdEntRdSigninRecordSuggest::getRecordId, recordId);

        List<DtrdEntRdSigninRecordSuggest> poList = list(queryWrapper);
        List<SigninRecordSuggestListInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
//            dtoList = poList.stream().map(SigninRecordSuggestListInfo::new).collect(Collectors.toList());
            dtoList = poList.stream().map(po -> {
                SigninRecordSuggestListInfo signinRecordSuggestListInfo = new SigninRecordSuggestListInfo(po);
                if (po.getSuggestDoctorId() != null) {
                    signinRecordSuggestListInfo.setSuggestDoctorName(doctorService.getDoctorName(po.getSuggestDoctorId()));
                }
                return signinRecordSuggestListInfo;
            }).collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public IPage<SigninRecordSuggestListInfo> pageSigninRecordSuggest(SigninRecordSuggestPageRequest request) {
        LambdaQueryWrapper<DtrdEntRdSigninRecordSuggest> queryWrapper = baseQueryWrapper();
        IPage<DtrdEntRdSigninRecordSuggest> page = new Page<>(request.getPageNum(), request.getPageSize());
        page = this.page(page, queryWrapper);
        return page.convert(SigninRecordSuggestListInfo::new);
    }

    @Override
    public SigninRecordSuggestDetail getSigninRecordSuggest(Integer dataId) {
        DtrdEntRdSigninRecordSuggest dtrdEntRdSigninRecordSuggest = getById(dataId);
        return Optional.ofNullable(dtrdEntRdSigninRecordSuggest)
                        .map(po -> new SigninRecordSuggestDetail().parseFromPo(po))
                        .orElse(null);
    }

    @Override
    public boolean saveOrUpdateSigninRecordSuggest(SigninRecordSuggestDetail dto) {
        DtrdEntRdSigninRecordSuggest dtrdEntRdSigninRecordSuggest = new DtrdEntRdSigninRecordSuggest();
        if(dto.getDataId() == null){
            dtrdEntRdSigninRecordSuggest = dtrdEntRdSigninRecordSuggest.init();
        }

        // 保存到建议
        SigninSuggestBean signinSuggestDetail = new SigninSuggestBean();
        signinSuggestDetail.setSigninType(dto.getSigninType());
        signinSuggestDetail.setSuggestContent(dto.getSuggest());
        signinSuggestDetail.setPatientId(dto.getPatientId());
        signinSuggestDetail.setRecordDate(DateUtils.formatDate(new Date()));
        rdSuggestService.saveOrUpdateSuggestRecord(signinSuggestDetail);

        if (dto.getSaveToTemplate() != null && dto.getSaveToTemplate() == 1) {
            // 保存到建议模板
            DoctorSigninSuggestDetail signinSuggest = new DoctorSigninSuggestDetail();
            signinSuggest.setSuggestContent(dto.getSuggest());
            signinSuggest.setSigninType(dto.getSigninType());
            signinSuggest.setDoctorId(dto.getSuggestDoctorId());
            signinSuggest.setOrgCode(dto.getOrgCode());
            signinSuggest.setTeamId(0);
            suggestService.saveDoctorSigninSuggest(signinSuggest);
        }
        dtrdEntRdSigninRecordSuggest.parseFromDto(dto);
        return saveOrUpdate(dtrdEntRdSigninRecordSuggest);
    }

    @Override
    public boolean removeSigninRecordSuggest(Integer dataId) {
        return removeById(dataId);
    }

    @Override
    public List<DtrdEntRdSigninRecordSuggest> getPeriodSigninRecordSuggest(Integer patientId, String startDate, String endDate) {
        return baseMapper.getPeriodSigninRecordSuggest(patientId, startDate, endDate);
    }

    @Override
    public Float getPatientSigninDietRecordScoreAvg(Integer patientId, String startDate, String endDate) {
//        获取打卡建议的列表
        List<DtrdEntRdSigninRecordSuggest> list = signinRecordSuggestService.getPeriodSigninRecordSuggest(patientId,startDate,endDate);
        System.out.println("查询到的长度：" + list.size());
        if(!list.isEmpty()){
//          将对象按照recordId转化为按照map格式，因为一条记录下有多个评分，取多个记录的评分的平均
            Map<Integer, List<DtrdEntRdSigninRecordSuggest>> integerListMap = list.stream().collect(Collectors.groupingBy(DtrdEntRdSigninRecordSuggest::getRecordId));
            final int[] result = new int[1];
            long mapCount = integerListMap.size();
            integerListMap.forEach((key, value)->{
                if (value != null) {
                    final int[] totalScore = new int[1];
                    value.forEach(l -> {
                        String[] scores = l.getScore().split(",");
                        int sumScore = 0;
                        for (String score : scores) {
                            try{
                                sumScore = sumScore + Integer.parseInt(score);
                            }catch (Exception e){
                                System.out.println("饮食平均分数计算格式转换错误:"+e.getMessage());
                            }
                        }
                        totalScore[0] = totalScore[0] + sumScore;
                    });
                    int sum = Arrays.stream(totalScore).sum();
                    long count = value.stream().count();
                    float score = count !=0?(float) (sum / count):0;
                    result[0] = result[0] + (int)score;
                }
            });
            float resultFloat = Arrays.stream(result).sum();
            System.out.println("最后的结果是：" + resultFloat);
            return mapCount != 0? (resultFloat / mapCount) :0;
        }
        return null;
    }

    @Override
    public PeriodFoodScore getFoodScoreForCharts(Integer patientId, String startDate, String endDate) {
        List<DtrdEntRdSigninRecordSuggest> list = baseMapper.getPeriodSigninRecordSuggest(patientId, startDate, endDate);
        PeriodFoodScore record = new PeriodFoodScore();
        List<String> dates = new ArrayList<>(list.size());
        List<Float> values = new ArrayList<>(list.size());
        List<Date> dateList = DateUtils.getDateList(DateUtils.str2Date(startDate,DateUtils.date_sdf.get()), DateUtils.str2Date(endDate,DateUtils.date_sdf.get()));
        for(Date date: dateList){
            dates.add(DateUtils.formatDate(date));
            Float score = getPatientSigninDietRecordScoreAvg(patientId, DateUtils.formatDate(date),DateUtils.formatDate(date));
            if(score == null) {
                values.add(0.0f);
            }
            values.add(score);
        }
        record.setDates(dates);
        record.setValues(values);
        return record;
    }

    private LambdaQueryWrapper<DtrdEntRdSigninRecordSuggest> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdSigninRecordSuggest.class)
                        .eq(DtrdEntRdSigninRecordSuggest::getIsDel, 0);
    }

    private LambdaUpdateWrapper<DtrdEntRdSigninRecordSuggest> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdEntRdSigninRecordSuggest.class)
                        .eq(DtrdEntRdSigninRecordSuggest::getIsDel, 0);
    }
}
